package club.kynb.mall.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import club.kynb.mall.order.api.IShoppingCartService;
import club.kynb.mall.order.model.dto.ShoppingCartDTO;
import club.kynb.mall.order.mysql.mapper.ShoppingCartMapper;
import club.kynb.mall.order.mysql.po.ShoppingCartPO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.constant.GlobalConstant;
import org.pizza.util.Convertor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author kynb_club@163.com
 * @since 2021/6/29 8:40 下午
 */
@Slf4j
@Service
@AllArgsConstructor
public class ShoppingCartServiceImpl implements IShoppingCartService {
    private final ShoppingCartMapper shoppingCartMapper;

    @Override
    public List<ShoppingCartDTO> userShoppingCart(Long userId) {
        final List<ShoppingCartPO> poList = shoppingCartMapper.selectList(Wrappers.<ShoppingCartPO>lambdaQuery().eq(ShoppingCartPO::getUserId, userId));
        return Convertor.convert(poList, ShoppingCartDTO.class);
    }

    @Override
    public void add(ShoppingCartDTO shoppingCartDTO) {
        ShoppingCartPO shoppingCartPO = shoppingCartMapper.selectOne(new QueryWrapper<ShoppingCartPO>().lambda()
                .eq(ShoppingCartPO::getUserId, shoppingCartDTO.getUserId())
                .eq(ShoppingCartPO::getSpuId, shoppingCartDTO.getSpuId())
                .eq(ShoppingCartPO::getSkuId, shoppingCartDTO.getSkuId())
        );
        if (shoppingCartPO == null) {
            shoppingCartPO = Convertor.convert(ShoppingCartPO.class, shoppingCartDTO);
            shoppingCartMapper.insert(shoppingCartPO);
        } else {
            shoppingCartPO.setSkuNum(shoppingCartPO.getSkuNum() + 1);
            shoppingCartPO.setChecked(GlobalConstant.YES);
            shoppingCartMapper.updateById(shoppingCartPO);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAdd(List<ShoppingCartDTO> cartList) {
        cartList.forEach(this::add);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reduce(Long userId, Long spuId, Long skuId, Integer num) {
        if (num == -1) {
            shoppingCartMapper.physicsDelete(userId, spuId, skuId);
        } else {
            ShoppingCartPO shoppingCartPO = shoppingCartMapper.selectOne(new QueryWrapper<ShoppingCartPO>().lambda()
                    .eq(ShoppingCartPO::getUserId, userId)
                    .eq(ShoppingCartPO::getSpuId, spuId)
                    .eq(ShoppingCartPO::getSkuId, skuId)
            );
            shoppingCartPO.setSkuNum(shoppingCartPO.getSkuNum() - num);
            if (shoppingCartPO.getSkuNum() <= 0) {
                shoppingCartMapper.physicsDelete(userId, spuId, skuId);
            } else {
                shoppingCartMapper.updateById(shoppingCartPO);
            }
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checked(Long userId, List<Long> checkedSkuIdList, List<Long> unCheckedSkuIdList) {
        if (CollectionUtil.isNotEmpty(checkedSkuIdList)) {
            final ShoppingCartPO shoppingCartPO = new ShoppingCartPO();
            shoppingCartPO.setChecked(GlobalConstant.YES);
            shoppingCartMapper.update(shoppingCartPO,
                    Wrappers.<ShoppingCartPO>lambdaUpdate().eq(ShoppingCartPO::getUserId, userId)
                            .in(ShoppingCartPO::getSkuId, checkedSkuIdList)
            );
        }
        if (CollectionUtil.isNotEmpty(unCheckedSkuIdList)) {
            final ShoppingCartPO shoppingCartPO = new ShoppingCartPO();
            shoppingCartPO.setChecked(GlobalConstant.NO);
            shoppingCartMapper.update(shoppingCartPO,
                    Wrappers.<ShoppingCartPO>lambdaUpdate().eq(ShoppingCartPO::getUserId, userId)
                            .in(ShoppingCartPO::getSkuId, unCheckedSkuIdList)
            );
        }
    }

    @Override
    public List<ShoppingCartDTO> getCheckedList(Long userId) {
        final List<ShoppingCartDTO> dtoList = this.userShoppingCart(userId);
        return dtoList.stream()
                .filter(dto -> dto.getChecked().equals(GlobalConstant.YES))
                .collect(Collectors.toList());
    }

    @Override
    public void clearShoppingCart(Long userId) {
        shoppingCartMapper.physicsDeleteBy(userId, GlobalConstant.YES);
    }
}
